package com.xzc._3_running;

import com.xzc._1_build.Base_Test;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.cdi.KSession;
import org.kie.api.marshalling.KieMarshallers;
import org.kie.api.marshalling.Marshaller;
import org.kie.api.marshalling.ObjectMarshallingStrategy;
import org.kie.api.marshalling.ObjectMarshallingStrategyAcceptor;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.KieSessionConfiguration;
import org.kie.api.runtime.conf.TimerJobFactoryOption;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * 装配器，可以动态的从KieService中装配或者卸载
 * 为session的持久化做准备
 */
public class Marshallers {

    Base_Test t = new Base_Test();
    KieBase kbase;
    KieSession ksession;

    public void init() {
        t.createContainerByClasspath();
        kbase = t.getKieContainer().getKieBase("KBase1");
        ksession = t.getKieContainer().newKieSession("KSession2_1");
    }

    /**
     * 从kbase仓库中开始，装配session
     * 默认实现类-SerializeMarshallingStrategy
     */
    public void marshaller() throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Marshaller marshaller = KieServices.Factory.get().getMarshallers().newMarshaller(kbase);
        marshaller.marshall(baos, ksession);
        baos.close();
    }

    /**
     * 使用Identify，他会产生一个INT值与所有的用户Data对应成一个MAP
     * 说这个是有状态的，在卸载的时候要小心，不明白
     *
     * @throws IOException
     */
    public void idMarshaller() throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        KieMarshallers kMarshallers = KieServices.Factory.get().getMarshallers();
        ObjectMarshallingStrategy oms = kMarshallers.newIdentityMarshallingStrategy();
        Marshaller marshaller = kMarshallers.newMarshaller(kbase, new ObjectMarshallingStrategy[]{oms});
        marshaller.marshall(baos, ksession);
        baos.close();
    }

    /**
     * 使用Acceptor来串行化装配器，这样就跟管道一样可以过滤一些东西
     * 序列化所有的类，除了某个包
     *
     * @throws IOException
     */
    public void useAcceptor() throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        KieMarshallers kMarshallers = KieServices.Factory.get().getMarshallers();
        ObjectMarshallingStrategyAcceptor identityAcceptor = kMarshallers.newClassFilterAcceptor(new String[]{"org.domain.pkg1.*"});
        ObjectMarshallingStrategy identityStrategy = kMarshallers.newIdentityMarshallingStrategy(identityAcceptor);
        ObjectMarshallingStrategy sms = kMarshallers.newSerializeMarshallingStrategy();
        Marshaller marshaller = kMarshallers.newMarshaller(kbase, new ObjectMarshallingStrategy[]{identityStrategy, sms});
        marshaller.marshall(baos, ksession);
        baos.close();
    }

    /**
     * 在装配定时规则时，要保证其是trackable的
     */
    public void marshallerJob() {
        KieSessionConfiguration ksconf = KieServices.Factory.get().newKieSessionConfiguration();
        ksconf.setOption(TimerJobFactoryOption.get("trackable"));
        KSession ksession = (KSession) kbase.newKieSession(ksconf, null);
    }
}
